package cosw.com.shanghaica.util;

import java.io.CharArrayWriter;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 
 * @author zhanglinhua
 * 
 */
public class StringUtil {

	public static byte[] getBCD(String phone) {
		if (phone.length() % 2 > 0)
			phone = phone + "F";
		if (phone == null)
			return null;
		byte[] result = new byte[phone.length() / 2];
		for (int i = 0; i < result.length; ++i) {
			int x = Integer.parseInt(phone.substring(i * 2, i * 2 + 2), 16);
			result[i] = x <= 127 ? (byte) x : (byte) (x - 256);
		}
		return result;
	}

	public static void byteArrayCopy(byte[] from, int off0, byte[] to,
			int off1, int len) {
		for (int i = 0; i < len; i++) {
			to[off1 + i] = from[off0 + i];
		}
	}

	public static byte[] getUnicode(String str) {
		char[] chars = str.toCharArray();
		byte[] result = new byte[chars.length * 2];
		for (int i = 0; i < chars.length; ++i) {
			result[2 * i] = (byte) (chars[i] / 256);
			result[2 * i + 1] = (byte) (chars[i] % 256);
		}
		return result;
	}

	public static final String HexCode[] = { "0", "1", "2", "3", "4", "5", "6",
			"7", "8", "9", "A", "B", "C", "D", "E", "F" };

	public static String getCASCIIString(byte[] data, int offset, int size) {
		CharArrayWriter out = new CharArrayWriter();
		for (int i = offset; i < size + offset; ++i) {
			if (data[i] == 0)
				break;
			out.write((char) data[i]);
		}
		return out.toString();
	}

	public static String getCUCS2String(byte[] data, int offset, int size) {
		try {
			int i;
			size = (size / 2) * 2;
			for (i = 0; i < size; i += 2) {
				if (data[offset + i] == 0 && data[offset + i + 1] == 0)
					break;
			}
			String str = new String(data, offset, i, "UTF-16BE");
			return new String(data, offset, i, "UTF-16BE");
		} catch (Exception e) {
		}
		return null;
	}

	public static String byteArrayToHexString(byte b[], int offset, int size) {
		if (b == null)
			return null;
		String result = "";
		for (int i = offset; i < offset + size; i++)
			result = result + byteToHexString(b[i]);
		return result;
	}

	public static String byteArrayToHexString(byte b[]) {
		if (b == null)
			return null;
		String result = "";
		for (int i = 0; i < b.length; i++)
			result = result + byteToHexString(b[i]);
		return result;
	}

	public static String byteArrayWithLenToHexString(byte b[], int off, int len) {
		if (b == null)
			return null;
		String result = "";
		for (int i = 0; i < len; i++)
			result = result + byteToHexString(b[off + i]);
		return result;
	}

	public static byte[] hexStringToByteArray(String text) {
		if (text == null)
			return null;
		text = text.replace(" ", "");

		byte[] result = new byte[text.length() / 2];
		for (int i = 0; i < result.length; ++i) {
			int x = Integer.parseInt(text.substring(i * 2, i * 2 + 2), 16);
			result[i] = x <= 127 ? (byte) x : (byte) (x - 256);
		}
		return result;
	}

	public static byte[] hexStringToAsciiByteArray(String text, int byteLen) {
		if (text == null)
			return null;
		byte[] result = new byte[(byteLen > text.length()) ? byteLen : text
				.length()];

		for (int i = 0; i < text.length(); i++) {
			int x = Integer.parseInt(text.substring(i, i + 1), 16);
			result[i] = (byte) ((byte) 0x30 + x);
		}

		return result;
	}

	public static String hexStringToString(String hexString, String charSet) {
		if (hexString == null)
			return null;
		String result = "";
		try {
			result = new String(hexStringToByteArray(hexString), charSet);
		} catch (Exception ex) {
		}
		return result;
	}

	public static String hexStringToAsciiString(String hexString) {
		return hexStringToString(hexString, "ASCII");
	}

	public static String byteToHexString(byte b) {
		int n = b;
		if (n < 0)
			n = 256 + n;
		int d1 = n / 16;
		int d2 = n % 16;
		return HexCode[d1] + HexCode[d2];
	}

	public static String longMoney2String(long money) {
		float m = ((float) money) / 100;
		return String.valueOf(m) + "元";
	}

	/**
	 * "3231" -> 21
	 * 
	 * @param ascStr
	 * @return
	 */
	public static String ascNumStr2HexStr(String ascStr) {
		StringBuilder sb = new StringBuilder();

		if ((ascStr.length() % 2) == 0) {
			for (int i = 0; i < ascStr.length(); i += 2)
				sb.append(ascStr.substring(i + 1, i + 2));
		}

		return sb.toString();
	}

	/**
	 * 手机号格式检查
	 * 
	 * @param mobiles
	 * @return
	 */
	public static boolean isMobileNO(String mobiles) {

		Pattern p = Pattern
				.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");

		Matcher m = p.matcher(mobiles);

		return m.matches();
	}

	/**
	 * 对double数据进行取精度.
	 * 
	 * @param value
	 *            double数据.
	 * @param scale
	 *            精度位数(保留的小数位数).
	 * @param roundingMode
	 *            精度取值方式.
	 * @return 精度计算后的数据.
	 */
	public static double doubleRound(double value, int scale, int roundingMode) {
		BigDecimal bd = new BigDecimal(value);
		bd = bd.setScale(scale, roundingMode);
		double d = bd.doubleValue();
		bd = null;
		return d;
	}

	/**
	 * 获取状态码， data + 9000 或 只有sw
	 * 
	 * @param res
	 * @return
	 */
	public static String getSWofResp(byte[] res) {
		return byteArrayToHexString(res).substring(res.length * 2 - 4);
	}

	public static String getSWofResp(String res) {
		return getSWofResp(StringUtil.hexStringToByteArray(res));
	}

	public static String getDataOfResp(byte[] res) {
		return byteArrayToHexString(res, 0, res.length - 2);
	}

	public static String getDataOfResp(String res) {
		return res.substring(0, res.length() - 4);
	}

	/**
	 * arr + off开始的len字节是否全为compareTo
	 * 
	 * @param arr
	 * @param off
	 * @param len
	 * @param compareTo
	 * @return
	 */
	public static boolean arrayCompareWithByte(byte[] arr, int off, int len,
			byte compareTo) {
		for (int i = 0; i < len; i++) {
			if (arr[off + i] != compareTo)
				return false;
		}

		return true;
	}

	public static void arrayFillWithBytes(byte[] arr, int off, int fillLen,
			byte fillByte) {
		for (int i = 0; i < fillLen; i++) {
			arr[off + i] = fillByte;
		}
	}

	public static boolean isStringEmpty(String str) {
		if (str != null && str.length() > 0) {
			if (str.equals("null")) {
				return true;
			} else {
				return false;
			}
		}

		return true;
	}

	public static short byte2Short(byte B) {
		return (short) (B & 0x00FF);
	}

	public static boolean isEmptyString(String str) {
		if (str == null || str.equals("") || str.length() == 0) {
			return true;
		}

		return false;
	}

	public static int hexBytes2Int(byte[] hexBytes, short off, short len) {
		int value = 0;

		for (short i = 0; i < len; i++) {
			value *= 256;
			value += byte2Short(hexBytes[off + i]);
		}

		return value;
	}

	/**
	 * 将value转化成hex数组。前补0
	 * 
	 * @param value
	 * @param bytes
	 *            ， 几个字节的数组
	 * @return
	 */
	public static byte[] int2HexBytes(int value, int bytes) {
		int temp = value;
		int i = 0;
		do {
			temp = temp / 256;
			i++;
		} while (temp > 0);

		if (bytes < i)
			return null;

		byte[] res = new byte[bytes];
		arrayFillWithBytes(res, 0, bytes, (byte) 0x00);

		temp = value;

		do {
			int left = temp % 256;
			// int x = Integer.parseInt(String.valueOf(left), 10);
			int x = left;
			res[bytes - 1] = ((x <= 127) ? (byte) x : (byte) (x - 256));

			temp = temp / 256;
			bytes--;
		} while (temp > 0);

		System.out.println("int value:" + String.valueOf(value));

		System.out.println("byteArrayToHexString:" + byteArrayToHexString(res));
		return res;
	}

	/**
	 * 返回对比结果 0为相等，负整数为小于，正整数为大于
	 * 
	 * @param s
	 * @param s_off
	 * @param t
	 * @param t_off
	 * @param len
	 */
	public static int byteArrayCompare(byte[] s, int s_off, byte[] t,
			int t_off, int len) {
		for (int i = 0; i < len; i++) {
			if (byte2Short(s[s_off + i]) < byte2Short(t[t_off + i])) {
				return -1;
			} else if (byte2Short(s[s_off + i]) > byte2Short(t[t_off + i])) {
				return 1;
			}
		}

		return 0;
	}

	/**
	 * 获取状态码， data + 9000 或 只有sw
	 * 
	 * @param res
	 * @return
	 */
	public static String getSWofApdu(byte[] res) {
		return byteArrayToHexString(res).substring(res.length * 2 - 4);
	}

	public static boolean checkSWofResp(byte[] res, byte sw1, byte sw2) {
		if (res != null && res.length >= 2 && res[res.length - 2] == sw1
				&& res[res.length - 1] == sw2) {
			return true;
		}

		return false;
	}

	public static boolean checkSW1ofResp(byte[] res, byte sw1) {
		if (res != null && res.length >= 2 && res[res.length - 2] == sw1) {
			return true;
		}

		return false;
	}

	public static byte[] getBytes(char[] chars) {
		Charset cs = Charset.forName("UTF-8");
		CharBuffer cb = CharBuffer.allocate(chars.length);
		cb.put(chars);
		cb.flip();
		ByteBuffer bb = cs.encode(cb);

		return bb.array();
	}

	public static char[] getChars(byte[] bytes) {
		Charset cs = Charset.forName("UTF-8");
		ByteBuffer bb = ByteBuffer.allocate(bytes.length);
		bb.put(bytes);
		bb.flip();
		CharBuffer cb = cs.decode(bb);

		return cb.array();
	}

	/**
	 * 从buff的subOff开始拷贝subLen返回;
	 * 
	 * @param buff
	 * @param subOff
	 * @param subLen
	 * @return
	 */
	public static byte[] subBytes(byte[] buff, short subOff, short subLen) {
		if ((subOff + subLen) > buff.length) {
			return null;
		}

		byte[] subBytes = new byte[subLen];
		StringUtil.byteArrayCopy(buff, subOff, subBytes, (short) 0, subLen);
		return subBytes;
	}

	/**
	 * 将一个int的值转化成10进制的数据存放在一个数组中返回，如0x100 -> [0x02, 0x56];
	 * 
	 * @param value
	 * @return
	 */
	public static byte[] int2ArrayInRadix10(int value) {
		int t = value;
		byte w = 0;
		do {
			w++;
			t = t / 10;
		} while (t > 0);

		byte[] res = new byte[(w + 1) / 2];

		t = value;
		w = 0;
		do {
			byte left = (byte) (t % 10);
			byte index = (byte) (res.length - 1 - (w / 2));
			if ((w % 2) == 0) { // 低4bit;
				res[index] = left;
			} else {
				// 高4bit;
				res[index] |= (byte) ((left << (byte) 0x04) & (byte) 0xF0);
			}

			w++;
			t = t / 10;
		} while (t > 0);

		return res;
	}
}
